package main

import (
	"bytes"
	"fmt"
	"image"
	"io"
	"strings"

	"code.google.com/p/go.net/html"
	"code.google.com/p/goplan9/draw"
)

var disp *draw.Display
var screen, back, grey, page *draw.Image
var dot, level int

func render_init() {
	errch := make(chan error)
	var err error
	fmt.Println(*fontpath)
	disp, err = draw.Init(errch, *fontpath, "<page title goes here>", "")
	die(err)
	go func() {
		for {
			die(<-errch)
		}
	}()
	screen = disp.ScreenImage
	back, err = disp.AllocImage(screen.R, screen.Pix, false, draw.White)
	die(err)
	grey, err = disp.AllocImage(screen.R, screen.Pix, false, draw.Palegreyblue)
	die(err)
	r := image.Rect(0, 0, 1000, 5000)
	page, err = disp.AllocImage(r, screen.Pix, false, draw.White)
	die(err)
}

func renderString(s string, col *draw.Image) {
	r := bytes.Runes([]byte(s))
	for len(r) > 0 {
		var line int
		if len(r) > 100 {
			line = 100
		} else {
			line = len(r)
		}
		pt := image.Pt(0, dot*disp.DefaultFont.Height)
		page.Runes(pt, col, image.ZP, disp.DefaultFont, r[:line])
		r = r[line:]
		dot++
	}
}

func printable(ntype string) bool {
	switch ntype {
	case "script":
		return false
	case "style":
		return false
	}
	return true
}

func renderNode(n *html.Node) {
	s := strings.TrimSpace(n.Data)
	if s != "" {
		var col *draw.Image
		if n.Type == html.TextNode {
			if *showtags == false && printable(n.Parent.Data) == false {
				return
			}
			col = disp.Black
			renderString(s, col)
		} else if *showtags {
			col = grey
			s = strings.Repeat("-", level) + s
			renderString(s, col)
		}
	}
}

func renderTree(tree *html.Node) {
	renderNode(tree)
	if tree.FirstChild != nil {
		level++
		renderTree(tree.FirstChild)
		level--
	}
	if tree.NextSibling != nil {
		renderTree(tree.NextSibling)
	}
}

func renderPage(body io.Reader) {
	tree, err := html.Parse(body)
	if err != nil {
		fmt.Println(err)
		return
	}
	renderTree(tree)
}

func redraw(new bool) {
	if new {
		if err := disp.Attach(draw.Refmesg); err != nil {
			fmt.Println("can't reattach to window:", err)
		}
	}
	screen.Draw(screen.R, back, nil, image.ZP)
	screen.Draw(page.R, page, nil, image.Pt(0, scroll*disp.DefaultFont.Height))
	//screen.FillEllipse(mousecoords, 5, 5, 5, disp.Black, image.ZP)

	disp.Flush()
}
